import threading
import time
import socket
# 这个方法是用来测试判断设备是否处于静止状态,使用wait_moves方法也可以
import serial


class SerialConn:
    def __init__(self, port, baudrate=115200):
        self.port = port
        self.baudrate = baudrate
        self.conn = None

    def open(self):
        self.conn = serial.Serial(self.port, self.baudrate, timeout=1)
        try:
            self.conn.close()
        except Exception:
            pass
        self.conn.open()

    def close(self):
        if self.conn and not self.conn.closed:
            self.conn.close()

    def send_cmd_with_res(self, cmd):

        #self.send_cmd(cmd)
        for i in range(5):
            self.send_cmd(cmd)
            
            time.sleep(0.1)
            res = self.recv_data()
            
            if "fail" in res:
               time.sleep(0.01)
            elif "success" in res:
               return res
        raise Exception(f"send_cmd_with_res fail, re_try {5}")

    def send_cmd(self, cmd):
        """

        """
        self.send_data((cmd + '\r\n').encode())

    def send_data(self, buffer):
        self.conn.write(buffer)

    def recv_data(self):
        return self.conn.readline().decode()


def busy_check_func(callback, check_busy, reactor):
    def run():
        while True:
            time.sleep(0.5)
            try:
                print_time, est_print_time, lookahead_empty = check_busy(
                    reactor.monotonic() + 2)
                help.log(
                    f"busy_check_func {est_print_time},{print_time},{lookahead_empty}")
                if est_print_time - print_time > 1 and lookahead_empty:
                    help.log("静止状态")
                    if callback:
                        callback()
                    break
            except Exception as e:
                help.log(f"busy_check_func 错误 {e}")
                break

    threading.Thread(target=run).start()


# udp广播数据到局域网
class MsgBroadUdp:
    def __init__(self, broad_address='255.255.255.255', broad_port=12343, interval=2, handel_msg_send=lambda: "data"):
        self.broad_address = broad_address
        self.broad_port = broad_port
        self.udp_socket = None
        self.interval = interval
        self.handel_msg_send = handel_msg_send
        self.running = False

    def init(self):
        self.udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.udp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)

    def _broad_thread(self):
        try:
            if not self.udp_socket:
                self.init()
            self.running = True
            while self.running:
                # 发送数据
                if self.handel_msg_send:
                    data = self.handel_msg_send()
                    self.udp_socket.sendto(data.encode(), (self.broad_address, self.broad_port))
                time.sleep(self.interval)
        except Exception as e:
            help.log(f"MsgBroadUdp error {e}")

    def start(self):
        if not self.running:
            threading.Thread(target=self._broad_thread).start()



